#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Copyright (C) 2011
# Free Software Foundation, Inc.
#
# This file is part of the gtk-fortran gtk+ Fortran Interface library.
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the GCC Runtime Library Exception, version
# 3.1, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License along with
# this program; see the files COPYING3 and COPYING.RUNTIME respectively.
# If not, see <http://www.gnu.org/licenses/>.
#
# Contributed by Vincent Magnin, 04.04.2011, Python 2.6.6, Linux Ubuntu 10.10
# Last modification: 06-27-2016 (python 3.5.1, Ubuntu 16.04)

""" This program helps you generating the USE statements for your gtk-fortran programs. It also
displays all the GTK+ functions used in a directory.
Command line: ./usemodules.py directorytoscan
"""

import os
import csv
import sys
import time
import re        # Regular expression library


def multiline(ch, maxlength):
    """Split a long line in a multiline, following Fortran syntax."""
    result = ""
    while len(ch) > maxlength-1:
        result += ch[0:maxlength-1] + "&\n"
        ch = "&"+ ch[maxlength-1:]
    result += ch
    return result


output_file = open("usemodules.txt", "w")
HEADER = """Generated by usemodules.py
Note that you should adapt these USE statements to each scoping unit.
The script just identifies all the functions used in a given file.
You will generally need to add:
  & g_signal_connect, gtk_init, FALSE, TRUE, CNULL, GDK_COLORSPACE_RGB, GDK_COLORSPACE_RGB,&
  & GTK_WINDOW_TOPLEVEL, NULL
You should also add enums identifiers and parameters.
\n
"""

output_file.write(HEADER)

used_functions = []
total = 0

# The script will work on all Fortran files in this directory and its subdirectories:
path = sys.argv[1]    # for example "../examples/"
if not path.endswith(os.sep):
    path += os.sep    # add directory separator on some operating systems

tree = os.walk(path)
for directory in tree:
    for f_name in directory[2]:
        # The gtk-fortran files are not treated:
        if "-auto" in f_name:
            continue    # to next file

        # Is it a Fortran file ?
        if f_name.endswith(".f90") or f_name.endswith(".f95") or f_name.endswith(".f03") or f_name.endswith(".f08"):
            print(f_name)

            only_dict = {}
            used_modules = []

            # Read the whole file in a string:
            whole_file = open(directory[0] + os.sep + f_name, 'rU').read()

            # Loading the GTK+ functions index generated by cfwrapper.py:
            reader = csv.reader(open("gtk-fortran-index.csv", "r"), delimiter=";")

            for row in reader:
                module_name = row[0]
                function_name = row[1]

                pattern = function_name + "[^a-zA-Z0-9_]"
                if re.search(pattern, whole_file) is not None:
                    # Is this module found for the first time ?
                    if module_name not in used_modules:
                        used_modules.append(module_name)
                        only_dict[module_name] = "use "+module_name+", only: "

                    only_dict[module_name] += function_name + ", "

                    # Is this GTK function found for the first time ?
                    if function_name not in used_functions:
                        used_functions.append(function_name)
                        total += 1

            # Writes the USE statements needed for this Fortran file:
            output_file.write(f_name+"\n"+"============\n")
            for key in list(only_dict.keys()):
                output_file.write(multiline(only_dict[key].rstrip(", "), 80)+"\n")
            output_file.write("\n\n")

output_file.close()

# To update the "Tested functions" wiki page:
used_functions.sort()

print()
print(total, "used functions, updated on", time.asctime(time.localtime()), "\n")
print(used_functions)
